package org.hepeng.workx.spring.cloud.netflix.zuul.route;

import org.joor.Reflect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter;
import org.tuckey.web.filters.urlrewrite.UrlRewriter;

import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * @author he peng
 */
public abstract class AbstractConfLoadUrlRewriteFilter extends UrlRewriteFilter {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractConfLoadUrlRewriteFilter.class);

    @Override
    protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
        try {
            loadUrlRewriterLocal();
        } catch(Throwable e) {
            LOG.error("load urlrewrite conf file error " , e);
            throw new ServletException(e);
        }
    }

    private void loadUrlRewriterLocal() throws Exception {
        Reflect thisReflect = Reflect.on(this);
        ServletContext context = thisReflect.get("context");
        String confPath = thisReflect.get("confPath");

        InputStream inputStream = context.getResourceAsStream(confPath);
        // attempt to retrieve from location other than local WEB-INF
        if ( inputStream == null ) {
            inputStream = ClassLoader.getSystemResourceAsStream(confPath);
        }
        URL confUrl = null;
        try {
            confUrl = context.getResource(confPath);
        } catch (MalformedURLException e) {
            LOG.error("" , e);
        }
        String confUrlStr = null;
        if (confUrl != null) {
            confUrlStr = confUrl.toString();
        }

        if (inputStream == null) {
            inputStream = loadUrlRewriterConf(confPath);
        }

        if (inputStream == null) {
            LOG.error("unable to find urlrewrite conf file at " + confPath);
            UrlRewriter urlRewriter = thisReflect.get("urlRewriter");
            // set the writer back to null
            if (urlRewriter != null) {
                LOG.error("unloading existing conf");
                thisReflect.set("urlRewriter" , null);
            }

        } else {
            boolean modRewriteStyleConf = thisReflect.get("modRewriteStyleConf");
            Conf conf = new Conf(context, inputStream, confPath, confUrlStr, modRewriteStyleConf);
            checkConf(conf);
        }
    }

    protected abstract InputStream loadUrlRewriterConf(String confPath) throws Exception;
}
